package zdar.screens;

import java.util.ArrayList;

import zdar.Zdar;
import zdar.entities.Unit;
import zdar.entities.UnitTemplate;
import zdar.processing.CharSheetDisplay;
import zdar.processing.XmlHandler;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Button;
import com.badlogic.gdx.scenes.scene2d.ui.ButtonGroup;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;

public class PreGameScreen implements Screen{

	final Zdar game;	
	OrthographicCamera camera;
	
	Stage stage;	
	Skin skin;
	SpriteBatch batch;
	//BitmapFont font;
	Table table;
	Table playerCharTable;
	Table enemyCharTable;
	Table playerStatsTable;
	Table enemyStatsTable;
	
	Button chooseCharacter, chooseEnemy, fight, quit;
	
	// These will hold all the labels that will need to be updated
	// They are separate than the actual Character Sheet (which doesn't really exist yet)
	CharSheetDisplay playerCharSheetDisplay;
	CharSheetDisplay enemyCharSheetDisplay;
	
	ArrayList<UnitTemplate> unitList = new ArrayList<UnitTemplate>();	// In the future this should be merged with the Character Sheet, somehow
	UnitTemplate playerChar;
	UnitTemplate enemyChar;
	
	public PreGameScreen(Zdar game){
		this.game = game;
		batch = new SpriteBatch();
		//skin = new Skin();
		skin = new Skin(Gdx.files.internal("skins/uiskin.json"));		
		skin.add("default", new BitmapFont());
		
		// Set the stage!
		stage = new Stage();
		Gdx.input.setInputProcessor(stage);		

		
		// Load unit data!
		XmlHandler xmlHandler = new XmlHandler();
		unitList = xmlHandler.getUnitList();
		System.out.println(unitList.toString());
		
		
		// Create a Table!
		setTables();		
			
		// Load images!
		
		// Load sounds!
		
		// Load music! (setLooping(true))
		
		// Create camera!
		camera = new OrthographicCamera();
		camera.setToOrtho(false, 1280, 720);	//TODO move sizes somewhere else
	}
	
	// Table Setups go here ==================================================================================================================================================
	// This method will set all the tables
	private void setTables(){
		table = new Table();
		stage.addActor(table);
		table.setSize(200, 720);
		table.setPosition(0, 0);
		table.left().top();
//		table.setDebug(true);
		setMainTable();
		
		playerCharTable = new Table();
		playerCharTable.setSize(200, 720);
		playerCharTable.setPosition(200, 0);
		playerCharTable.left().top();
//		playerCharTable.setDebug(true);
		setPlayerCharSelectTable();
		
		enemyCharTable = new Table();
		enemyCharTable.setSize(200, 720);
		enemyCharTable.setPosition(200, 0);
		enemyCharTable.left().top();
//		enemyCharTable.setDebug(true);
		setEnemyCharSelectTable();	
		
		playerStatsTable = new Table();
		stage.addActor(playerStatsTable);
		playerStatsTable.setSize(880, 360);
		playerStatsTable.setPosition(400, 360);
		playerStatsTable.left();
//		playerStatsTable.setDebug(true);
		setPlayerStatsTable();
		
		enemyStatsTable = new Table();
		stage.addActor(enemyStatsTable);
		enemyStatsTable.setSize(880, 360);
		enemyStatsTable.setPosition(400, 0);
		enemyStatsTable.left();
//		enemyStatsTable.setDebug(true);
		setEnemyStatsTable();

	}

	private void setMainTable(){
		chooseCharacter = new TextButton("Choose Character", skin, "toggle");
		chooseCharacter.addListener(new ChangeListener(){
			public void changed(ChangeEvent event, Actor actor) {
				enemyCharTable.remove();
				stage.addActor(playerCharTable);				
			}			
		});
		chooseEnemy = new TextButton("Choose Opponent", skin, "toggle");
		chooseEnemy.addListener(new ChangeListener(){
			public void changed(ChangeEvent event, Actor actor) {
				playerCharTable.remove();
				stage.addActor(enemyCharTable);
			}			
		});
		fight = new TextButton("FIGHT!", skin, "toggle");
		fight.addListener(new ChangeListener(){
			public void changed(ChangeEvent event, Actor actor) {
				System.out.println("FIGHT!");
				
				game.setScreen(new FightScreen(game, playerChar, enemyChar));
			}			
		});
		quit = new TextButton("Quit", skin, "toggle");
		quit.addListener(new ChangeListener(){
			public void changed(ChangeEvent event, Actor actor) {
				System.out.println("DIE!");
				Gdx.app.exit();
			}			
		});

		table.add(chooseCharacter).width(200).height(50);
		table.row();
		table.add(chooseEnemy).width(200).height(50);
		table.row();
		table.add(new Label("======================", skin));
		table.row();
		table.add(fight).width(200).height(50);
		table.row();
		table.add(quit).width(200).height(50);
		
		fight.setDisabled(true); // Should not be usable until Player and Opponent chars have been chosen
		fight.setVisible(false);
		
		ButtonGroup buttongroup = new ButtonGroup(chooseCharacter, chooseEnemy);
		buttongroup.setMaxCheckCount(1);
		buttongroup.setMinCheckCount(0);
		buttongroup.setUncheckLast(true);
	}
	
	private void setPlayerCharSelectTable(){
		ButtonGroup buttongroup = new ButtonGroup();
		buttongroup.setMaxCheckCount(1);
		buttongroup.setMinCheckCount(0);
		buttongroup.setUncheckLast(true);		
		
		for (UnitTemplate u : unitList){
			final UnitTemplate u2 = u;

			Button button = new TextButton(u2.getDisplayName(), skin, "toggle");
			button.addListener(new ChangeListener(){
				public void changed(ChangeEvent event, Actor actor){
					System.out.println(u2.getDescription());
					playerChar = u2;
					playerCharSheetDisplay.changeUnitType(playerChar);
					//playerChar.setCharSheetDisplay(playerCharSheetDisplay);
					playerChar.charSheetDisplay = playerCharSheetDisplay;
				}
			});
			playerCharTable.add(button).width(200).height(50);
			playerCharTable.row();
			buttongroup.add(button);
		}
	}
	private void setEnemyCharSelectTable(){
		ButtonGroup buttongroup = new ButtonGroup();
		buttongroup.setMaxCheckCount(1);
		buttongroup.setMinCheckCount(0);
		buttongroup.setUncheckLast(true);		
		
		for (UnitTemplate u : unitList){
			final UnitTemplate u2 = u;

			Button button = new TextButton(u2.getDisplayName(), skin, "toggle");
			button.addListener(new ChangeListener(){
				public void changed(ChangeEvent event, Actor actor){
					System.out.println(u2.getDescription());
					enemyChar = u2;
					enemyCharSheetDisplay.changeUnitType(enemyChar);	// TODO this might get messy....
//					enemyChar.setCharSheetDisplay(enemyCharSheetDisplay);
					enemyChar.charSheetDisplay = enemyCharSheetDisplay;
				}
			});
			enemyCharTable.add(button).width(200).height(50);
			enemyCharTable.row();
			buttongroup.add(button);
		}
	}
	private void setPlayerStatsTable(){	// TODO might not be a bad idea to have a special class for CharDisplays... someday
		playerCharSheetDisplay = new CharSheetDisplay(skin);
		playerStatsTable.add(new Label("Name: ", skin)).left();
		playerStatsTable.add(playerCharSheetDisplay.getName()).left();
		playerStatsTable.row();
		playerStatsTable.add(new Label("Description: ", skin)).left();
		playerStatsTable.add(playerCharSheetDisplay.getDescription()).left();
		playerStatsTable.row();
		playerStatsTable.add(new Label("Wounds: ", skin)).left();
		playerStatsTable.add(playerCharSheetDisplay.getWounds()).left();
		playerStatsTable.row();
		playerStatsTable.add(new Label("Fatigue: ", skin)).left();
		playerStatsTable.add(playerCharSheetDisplay.getFatigue()).left();
	}
	private void setEnemyStatsTable(){	// TODO might not be a bad idea to have a special class for CharDisplays... someday
		enemyCharSheetDisplay = new CharSheetDisplay(skin);
		enemyStatsTable.add(new Label("Name: ", skin)).left();
		enemyStatsTable.add(enemyCharSheetDisplay.getName()).left();
		enemyStatsTable.row();
		enemyStatsTable.add(new Label("Description: ", skin)).left();
		enemyStatsTable.add(enemyCharSheetDisplay.getDescription()).left();
		enemyStatsTable.row();
		enemyStatsTable.add(new Label("Wounds: ", skin)).left();
		enemyStatsTable.add(enemyCharSheetDisplay.getWounds()).left();
		enemyStatsTable.row();
		enemyStatsTable.add(new Label("Fatigue: ", skin)).left();
		enemyStatsTable.add(enemyCharSheetDisplay.getFatigue()).left();
	}
	
	// Default Methods=============================================================================================================================
	public void update(){
		// Check for conditions
		if (playerChar != null && enemyChar != null){
			
			fight.setDisabled(false);
			fight.setVisible(true);
		}
	}
	
	@Override
	public void render(float delta) {
		// Clear the screen with some tasty dark blue
		Gdx.gl.glClearColor(0, 0, 0.2f, 1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
		stage.act();
		stage.draw();	
		
		// tell camera to get its shit together and update its matrices
		camera.update();
		
		// tell the sprite to render in coord system set by camera
		game.batch.setProjectionMatrix(camera.combined);
		
		// begin a new batch and draw things again
		game.batch.begin();
		//game.font.draw(game.batch, "Hey look, text!", 1150, 720);
		//game.batch.draw(someShit, some, where);
		game.batch.end();
		
		// process user input
		if (Gdx.input.isKeyPressed(Keys.A)){	//wow this not good for just selecting things once
			System.out.println("You pressed A!");
		}
		
		// do some update checks to see if anything has changed.
		update();	//or just do it all in there.

	}

	@Override
	public void resize(int width, int height) {
		// stage.getViewport().update(width, height, true);
	}

	@Override
	public void show() {
		//play music!
	}

	@Override
	public void hide() {
	}

	@Override
	public void pause() {
	}

	@Override
	public void resume() {
	}

	@Override
	public void dispose() {
		//dipose images
		//dispose sounds
		// I guess that's all
		stage.dispose();
		skin.dispose();
	}
}
